using System.CodeDom;
using System.Collections.Generic;
using System.Linq;

namespace InterfaceWeaver.CustomTool
{
    public class CodeMemberPropertyContext
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="CodeMemberPropertyContext" /> struct.
        /// </summary>
        /// <param name="codeMemberProperty">The code member property.</param>
        /// <param name="codeMemberField">The code member field.</param>
        /// <param name="setterCodeCoreStream">The setter code core stream.</param>
        /// <param name="setterAssignStatment">The setter assign expression.</param>
        /// <param name="hooks">The hooks.</param>
        public CodeMemberPropertyContext(
            CodeMemberProperty codeMemberProperty, 
            CodeMemberField codeMemberField, 
            CodeStatementCollection setterCodeCoreStream,
            CodeAssignStatement setterAssignStatment,
            params CodeTypeMember[] hooks)
        {
            this.CurrentCodeMemberPropertyDeclaration = codeMemberProperty;
            this.CurrentCodeMemberFieldDeclaration = codeMemberField;
            this.SetterCodeCoreStream = setterCodeCoreStream;
            this.SetterAssignStatment = setterAssignStatment;
            this.Hooks = hooks.ToList();
        }

        /// <summary>
        /// Gets the current code member property declaration.
        /// </summary>
        public CodeMemberProperty CurrentCodeMemberPropertyDeclaration { get; private set; }


        /// <summary>
        /// Gets the current code member field declaration.
        /// </summary>
        public CodeMemberField CurrentCodeMemberFieldDeclaration { get; private set; }

        /// <summary>
        /// Gets the setter code core stream.
        /// </summary>
        public CodeStatementCollection SetterCodeCoreStream { get; private set; }

        /// <summary>
        /// Gets the setter assign expression.
        /// </summary>
        public CodeStatement SetterAssignStatment { get; private set; }

        /// <summary>
        /// Gets or sets the hooks.
        /// </summary>
        public List<CodeTypeMember> Hooks { get; private set; }

        /// <summary>
        /// Updates the setter code stream.
        /// </summary>
        /// <param name="newCodeStream">The new code stream.</param>
        public void UpdateSetterCodeStream(CodeStatementCollection newCodeStream)
        {
            this.SetterCodeCoreStream = newCodeStream;
        }

        /// <summary>
        /// Updates the setter code stream.
        /// </summary>
        /// <param name="assignStatment">The assign expression.</param>
        public void UpdateSetterAssignExpression(CodeStatement assignStatment)
        {
            this.SetterAssignStatment = assignStatment;
        }

        /// <summary>
        /// Updates the member field.
        /// </summary>
        /// <param name="newCodeMemberField">The new code member field.</param>
        public void UpdateMemberField(CodeMemberField newCodeMemberField)
        {
            this.CurrentCodeMemberFieldDeclaration = newCodeMemberField;
        }
    }
}